
/****************************************************************************
**
** Copyright (C) 2004-2008 VATATA.com . All rights reserved.
**
** This file is the part of the Miniutil Poject of VATATA.com.
** Vatata's miniutil library is lightweight and portable (for linux
** and Windows). The C++ Class Library included Threadpool, Dll danymic loading, 
** General socket application model and tcp server, httpserver/servlet, etc. 
** It is a pratical utility disigned for who don't want learn the Big C++ 
** Developing Platform, such as  Boost or ACE.
**
** This file may be used under the terms of the GNU General Public
** License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file.  Alternatively you may (at
** your option) use any later version of the GNU General Public
** License if such license has been publicly approved by VATATA.com.
** (or its successors, if any) and the Miniutil Project Aministrators. 
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://www.gnu.org/licenses/lgpl.html. If you are unsure which 
** license is appropriate for your use, please review the following 
** information: http://code.google.com/p/miniutil/ or contact 
** http://www.vatata.com.
**
** In addition, as a special exception, VATATA.com, as the sole
** copyright holder for Miniutil Project, grants users of VATATA
** P2P Platform the right to release and package with the related 
** libraries without the source code.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. vatata reserves all rights not expressly
** granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/



#include "miniutil/srtti.h"
#include "miniutil/log.h"


using namespace miniutil::srtti;

miniutil::srtti::manager * miniutil::srtti::manager::_manager = NULL;


manager::manager()
{
}


int  manager::_set(const char *instance_name, void *instance)
{
	std::string name( instance_name );
	if ( _manager == NULL )
		_manager = new miniutil::srtti::manager();
	_manager->_managerMap[ name ] = instance;
	return (int)_manager->_managerMap.size();
}

void * manager::_get( const char * instance_name )
{
	std::string name( instance_name );
	if ( _manager == NULL )
	{
		_manager = new miniutil::srtti::manager();
		return NULL;
	}
	return _manager->_managerMap[ name ] ;
}

int manager::_set(const std::string & name, void *instance)
{
	if ( _manager == NULL )
		_manager = new miniutil::srtti::manager();
	_manager->_managerMap[ name ] = instance;
	return (int)_manager->_managerMap.size();
}

void * manager::_get( const  std::string & name )
{
	if ( _manager == NULL )
	{
		_manager = new miniutil::srtti::manager();
		return NULL;
	}
	return _manager->_managerMap[ name ] ;
}


const char * miniutil::srtti::srtti::CREATE_FUNC_NAME = "miniutil_srtti_create";
const char * miniutil::srtti::srtti::DESTROY_FUNC_NAME = "miniutil_srtti_destroy";

#ifdef _DEBUG
const char * miniutil::srtti::srtti::VERSION = "srtti_0.0.1_debug";
#else
const char * miniutil::srtti::srtti::VERSION = "srtti_0.0.1_release";
#endif

int srtti::_declare( const char * dll_path, const char * classname , const char * create_func , const char * destroy_func  )
			{
				if ( classname == NULL || *classname == 0 ) return -1;
				std::string name(classname2name(classname) );

				void * ptr = manager::_get( name );
				if ( ptr != NULL )
				{
					//	delete ptr;  
				// todo , delete void * !
					M_DEBUG( "declare a exist class %s\r\n", classname );
				}
				dll_worker * w = new dll_worker();
				w->classname = classname;

				w->p_lib = miniutil::dll::library::getDll( dll_path , VERSION );
				w->p_create = NULL;
				if ( w->p_lib )
				{
					w->p_create =   (dll_create_t) w->p_lib->getFunc( create_func );
					w->p_destroy = (dll_destroy_t) w->p_lib->getFunc( destroy_func );
				}

				if ( w->p_create )
					return manager::_set( name, w );

				M_DEBUG( "can not load dll file %s  %p %p\r\n", dll_path , w->p_lib, w->p_create  );
				delete w;
				return -1;
			}

void * srtti::_newInstance( const char * classname )
			{
				if ( classname == NULL || *classname == 0 ) return NULL;
				std::string name(classname2name(classname) );

				worker * ptr = (worker * )manager::_get( name );
				if ( ptr == NULL )
					return NULL;

				return  ptr->_new();
			}

void srtti::_destroyInstance( const char * classname, void * p )
			{
				if ( classname == NULL || *classname == 0 ) return ;
				std::string name(classname2name(classname) );

				worker * ptr = (worker * )manager::_get( name );
				if ( ptr == NULL )
					return ;

				return  ptr->_delete( p );
			}




extern "C" 
{
	void * miniutil_srtti_create( const char * classname )
	{
		if ( classname == NULL )
			return NULL;

		return srtti::_newInstance( classname );
	}


	void  miniutil_srtti_destroy( const char * classname, void * p )
	{
		if ( classname == NULL )
			return ;
		srtti::_destroyInstance( classname, p );
	}

}

